package com.ysz.redisson.config;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

/**
 * @ClassName RedisEncapsulation
 * @Description TODO
 * @Data 13:32
 * @Version 1.0
 * @Author ysz
 */
public class RedisEncapsulation {


    /**
     * 注意注入对象，别注入错了，错了序列化不一致，从redis取不出东西来
     */
    private static RedisTemplate<String, Object> redisTemplate;

    static {
        redisTemplate = SpringUtils.getBeanByName("getRedisTemplate");
    }


    /**
     * 给key增加增量(increment)
     *
     * @param key       key
     * @param increment 给指定的key增加increment
     * @author ysz
     * @date 2021/8/2 13:46
     */
    public static void increment(String key, Long increment) {
        redisTemplate.opsForValue().increment(key, increment);
    }


    /**
     * 给key增加增量(increment)
     *
     * @param key       key
     * @param increment 给指定的key增加increment
     * @author ysz
     * @date 2021/8/2 13:46
     */
    public static void increment(String key, Double increment) {
        redisTemplate.opsForValue().increment(key, increment);
    }


    /**
     * 从redis中获取
     *
     * @param key key
     * @return value
     * @author ysz
     * @date 2021/8/2 13:48
     */
    @SuppressWarnings("all")
    public static <T> T get(String key) {
        return (T) redisTemplate.opsForValue().get(key);
    }


    /**
     * 删除redis中key所对应的值
     *
     * @param key key
     * @return true / false
     * @author ysz
     * @date 2021/8/3 16:57
     */
    @SuppressWarnings("all")
    public static boolean delete(String key) {
        return redisTemplate.delete(key);
    }


    /**
     * 删除redis中key所对应的值
     *
     * @param key key
     * @return true / false
     * @author ysz
     * @date 2021/8/3 16:57
     */
    @SuppressWarnings("all")
    public static boolean deleteMap(String key, Object... keys) {
        return redisTemplate.opsForHash().delete(key, keys) == keys.length ? true : false;
    }


    /**
     * 新增带时间
     *
     * @param key      key
     * @param value    value
     * @param time     时间
     * @param timeUnit 时间单位
     * @author ysz
     * @date 2021/8/2 13:52
     */
    public static <T> void set(String key, T value, Long time, TimeUnit timeUnit) {
        redisTemplate.opsForValue().set(key, value, time, timeUnit);
    }


    /**
     * 新增带时间
     *
     * @param key   key
     * @param value value
     * @author ysz
     * @date 2021/8/2 13:52
     */
    public static <T> void set(String key, T value) {
        redisTemplate.opsForValue().set(key, value);
    }


    /**
     * 新增如果不存在返回true  相当于redis的set nx命令
     *
     * @return true/false
     * @author ysz
     * @date 2021/8/2 16:06
     */
    @SuppressWarnings("all")
    public static <T> boolean setNx(String key, T value, Long time, TimeUnit timeUnit) {
        return redisTemplate.opsForValue().setIfAbsent(key, value, time, timeUnit);
    }


    /**
     * 新增如果存在返回true  相当于redis的set xx命令
     *
     * @return true/false
     * @author ysz
     * @date 2021/8/2 16:06
     */
    @SuppressWarnings("all")
    public static <T> boolean setXx(String key, T value, Long time, TimeUnit timeUnit) {
        return redisTemplate.opsForValue().setIfPresent(key, value, time, timeUnit);
    }


    /**
     * 对该key递减
     *
     * @return 减后的值
     * @author ysz
     * @date 2021/8/2 16:08
     */
    public static <T> Long decrement(String key) {
        return redisTemplate.opsForValue().decrement(key);
    }


    /**
     * 对该key减decrement量
     *
     * @return 减后的值
     * @author ysz
     * @date 2021/8/2 16:08
     */
    public static <T> void decrement(String key, Long decrement) {
        redisTemplate.opsForValue().decrement(key, decrement);
    }


    /**
     * 对该key拼接value
     *
     * @author ysz
     * @date 2021/8/2 16:08
     */
    public static <T> void append(String key, String value) {
        if (Optional.ofNullable(key).isPresent()) {
            redisTemplate.opsForValue().append(key, value);
        }
    }


    /**
     * 批量新增传递一个map即可
     *
     * @param map key必须是string
     * @author ysz
     * @date 2021/8/2 16:22
     */
    public static <T extends String> void multiSet(Map<T, ?> map) {
        redisTemplate.opsForValue().multiSet(map);
    }


    /**
     * 批量获取 需要传递collection子类
     *
     * @param collection 集合
     * @author ysz
     * @date 2021/8/2 16:22
     */
    @SuppressWarnings("all")
    public static <T extends String> List<Object> multiGet(Collection<T> collection) {
        return redisTemplate.opsForValue().multiGet((Collection<String>) collection);
    }


    /**
     * 使用redis的set集合类型添加元素
     *
     * @author ysz
     * @date 2021/11/19 9:33
     */
    @SafeVarargs
    public static <T> Long add(String key, T... values) {
        return redisTemplate.opsForSet().add(key, values);
    }


    /**
     * 移除set集合中的一个元素
     *
     * @author ysz
     * @date 2021/11/19 9:59
     */
    @SafeVarargs
    public static <T> Long rem(String key, T... values) {
        return redisTemplate.opsForSet().remove(key, values);
    }


    /**
     * 返回set集合中的所有元素
     *
     * @author ysz
     * @date 2021/11/19 10:07
     */
    public static <T> T membersAll(String key) {
        return (T) redisTemplate.opsForSet().members(key);
    }


    /**
     * lua脚本执行器
     *
     * @param args 时间为毫秒
     * @author ysz
     * @date 2021/11/27 13:00
     */
    public static <T> T execute(Class<T> tClass, String lua, List<String> keys, Object... args) {
        DefaultRedisScript<T> script1 = new DefaultRedisScript<>();
        script1.setScriptText(lua);
        script1.setResultType(tClass);
        return redisTemplate.execute(script1, keys, args);
    }
}
